package com.macro.mall.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.macro.mall.bean.entity.OdrOrder;
import com.macro.mall.bean.entity.OdrOrderFlowLog;
import com.macro.mall.bean.entity.OdrOrderPay;
import com.macro.mall.bean.vo.*;
import com.macro.mall.common.api.SMSSend;
import com.macro.mall.common.api.SMSSendCode;
import com.macro.mall.constans.Constans;
import com.macro.mall.dao.OdrOrderDao;
import com.macro.mall.dao.OdrOrderFlowLogDao;
import com.macro.mall.dao.OdrOrderPayDao;
import com.macro.mall.exception.BaseException;
import com.macro.mall.mapper.PmProdServiceTypeMapper;
import com.macro.mall.mapper.PmProdSpecMapper;
import com.macro.mall.mapper.PmProductMapper;
import com.macro.mall.model.*;
import com.macro.mall.util.CreateID;
import com.macro.mall.util.ValidatorUtil;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OdrOrderService {

    @Autowired
    OdrOrderDao odrOrderDao;
    @Autowired
    OdrOrderFlowLogDao odrOrderFlowLogDao;
    @Autowired
    OdrOrderPayDao odrOrderPayDao;
    @Autowired
    private PmProdStockService pmProdStockService;
    @Autowired
    private PmProdSpecMapper prodSpecMapper;
    @Autowired
    private PmProductMapper productMapper;
    @Autowired
    private PmProdServiceTypeMapper prodServiceTypeMapper;

    public String commit(OrderCommitReqVO request) {
        try {
            OdrOrder odrOrder = new OdrOrder();
            SimpleDateFormat sp = new SimpleDateFormat("yyyyMMddHHmmss");
            BeanUtils.copyProperties(request, odrOrder);
            budData(request,odrOrder);

            /*odrOrder.setServiceSTime(sp.parse(request.getServiceSTime()));
            odrOrder.setServiceETime(sp.parse(request.getServiceETime()));*/
            //TODO 调用库存扣减
            Float goodCountF;
            Long stockId;
            if("11".equals(odrOrder.getOrderType())){
                try {
                    goodCountF = Float.valueOf(request.getGoodCount());
                    stockId = Long.valueOf(request.getStockId());
                }catch (Exception ex){
                    log.error("库存扣减失败: ", ex);
                    throw new BaseException("库存扣减失败：参数转换失败 goodCount= "+request.getGoodCount()+ "   stockId="+request.getStockId());
                }
                PmProdStock prodStock  = pmProdStockService.deductStock(stockId,goodCountF,odrOrder.getOrderId());

                if(prodStock==null){
                    throw new BaseException("订单提交失败:扣减库存失败！");
                }
                odrOrder.setGoodId(prodStock.getProdId().toString());
            }else if("12".equals(odrOrder.getOrderType())){
                String stockCode="";
                try {
                    goodCountF = Float.valueOf(request.getGoodCount());
                    stockCode =  request.getStockId();
                }catch (Exception ex){
                    log.error("库存扣减失败: ", ex);
                    throw new BaseException("库存扣减失败：参数转换失败 goodCount= "+request.getGoodCount()+ "   stockId="+request.getStockId());
                }
                if(StringUtils.isBlank(stockCode)){
                    log.error("上门服务 skuCode 不问为空！");
                    throw new BaseException("库存扣减失败：参数转换失败 goodCount= "+request.getGoodCount()+ "   stockId="+request.getStockId());
                }
                try {
                    PmProdStock prodStock = pmProdStockService.deductStockByDoor(request.getServerStockByDoor(), request.getStockDate(), request.getStockTime(), goodCountF, odrOrder.getOrderId());
                    if (prodStock ==null) {
                        log.error("订单提交失败:扣减库存失败");
                        throw new Exception("订单提交失败:扣减库存失败！orderId="+odrOrder.getOrderId());
                    }
                    odrOrder.setGoodId(prodStock.getProdId().toString());
                }catch (Exception e){
                    throw new Exception(e.getMessage()+" orderId = " +odrOrder.getOrderId());
                }
            }
            try {
                //todo 暂时逻辑，后续要调用商品模块接口
                String serviceModeName="";
                String specName="";
                PmProduct product =  productMapper.selectByPrimaryKey(Long.valueOf(odrOrder.getGoodId()));
                PmProdSpec prodSpec;
                if(product!=null){
                    prodSpec = prodSpecMapper.selectByPrimaryKey(product.getProdSpecId());

                    specName =prodSpec.getSpecName();

                    PmProdServiceTypeExample example = new PmProdServiceTypeExample();
                    PmProdServiceTypeExample.Criteria criteria = example.createCriteria();
                    criteria.andProdIdEqualTo(product.getId());
                    List<PmProdServiceType> list = prodServiceTypeMapper.selectByExample(example);
                    if(list!=null){
                        PmProdServiceType serverType = list.get(0);
                        serviceModeName=serverType.getServiceTypeName();
                    }
                }

//                String masage = SMSSendCode.appointment.getMasage();
//                SMSSend.sendSMS(request.getMobile(),
//                        masage.replaceAll("xcode",serviceModeName).replaceAll("xname",specName),
//                        SMSSendCode.appointment.getCode());
            } catch (Exception e) {
                log.error("短信发送失败: ", e);
            }

            odrOrderDao.insert(odrOrder);
            return odrOrder.getOrderId();
        } catch (Exception e) {
            log.error("订单提交失败: ", e);
            throw new BaseException("订单提交失败");
        }
    }

    private void budData(OrderCommitReqVO request, OdrOrder odrOrder) {
        Date createTime = new Date();
        odrOrder.setCreateTime(createTime);
        odrOrder.setMakeAppointment(DateUtil.parse(request.getMakeAppointment(), "yyyy-MM-dd HH:mm:ss"));
        // 获取取消订单时间
        long time1 = createTime.getTime();
        long time = time1 += 30 * 60 * 1000;
        odrOrder.setPayEffect(new Date(time));
        odrOrder.setOrderId(CreateID.createID());
        if ("00".equals(odrOrder.getOrderPayType())) {
            odrOrder.setOrderStatus("002");
        }
    }


    @Transactional
    public void statusUpdate(OrderStatusUpdateReqVO request) {
        try {
            //TODO 如取消订单(支付完成状态) 则需要调用库存回退
            boolean stockFlag = pmProdStockService.rollbackStockSimplify(request.getOrderId());
            if(!stockFlag){
                throw new BaseException("订单提交失败:库存回退失败！");
            }
            //校验订单存在
            OdrOrder odrOrder = odrOrderDao.selectByPrimaryKey(request.getOrderId());
            if (odrOrder == null) {
                throw new BaseException("订单不存在");
            }
            //校验当前状态（与订单状态是否一致）
            if (!request.getPreStatus().equals(odrOrder.getOrderStatus())) {
                throw new BaseException("当前状态与订单状态不一致");
            }
            // 校验目标状态 002 待服务->insert orderPay表
            OdrOrderPay odrOrderPay = new OdrOrderPay();
            if (request.getTargetStatus().equals(Constans.WAIT_SERVE)) {
                OdrOrderPayReqVO odrOrderPayReqVO = request.getOdrOrderPay();
                if (odrOrderPayReqVO == null) {
                    throw new BaseException("目标状态为待服务时，odrOrderPay不能为空");
                }
                //校验odrOrderPayReqVO类的属性
                checkOrderPay(odrOrderPayReqVO);
                //写入订单支付表
                BeanUtils.copyProperties(odrOrderPayReqVO, odrOrderPay);
                odrOrderPay.setPayTime(new SimpleDateFormat("yyyyMMddHHmmss").parse(odrOrderPayReqVO.getPayTime()));
                try {
                    //todo 暂时逻辑，后续要调用商品模块接口
                    String serviceModeName="";
                    String specName="";
                    PmProduct product =  productMapper.selectByPrimaryKey(Long.valueOf(odrOrder.getGoodId()));
                    PmProdSpec prodSpec;
                    if(product!=null){
                        prodSpec = prodSpecMapper.selectByPrimaryKey(product.getProdSpecId());
                        specName =prodSpec.getSpecName();
                        PmProdServiceTypeExample example = new PmProdServiceTypeExample();
                        PmProdServiceTypeExample.Criteria criteria = example.createCriteria();
                        criteria.andProdIdEqualTo(product.getId());
                        List<PmProdServiceType> list = prodServiceTypeMapper.selectByExample(example);
                        if(list!=null){
                            PmProdServiceType serverType = list.get(0);
                            serviceModeName=serverType.getServiceTypeName();
                        }
                    }

                    String masage = SMSSendCode.appointment.getMasage();
                    SMSSend.sendSMS(odrOrder.getMobile(),
                            masage.replaceAll("xcode",serviceModeName).replaceAll("xname",specName),
                            SMSSendCode.appointment.getCode());
                } catch (Exception e) {
                    log.error("短信发送失败: ", e);
                }
                odrOrderPayDao.deleteByPayNo(odrOrderPayReqVO.getPayNo());
                odrOrderPayDao.insert(odrOrderPay);
            }
            // 校验目标状态 007 退款中 -> update order表中 caseReturnStatus，caseReturnResult
            if (request.getTargetStatus().equals(Constans.REFUND_PAY_ING)) {
                OdrOrderRefundReqVO odrOrderRefund = request.getOdrOrderRefund();
                if (odrOrderRefund == null) {
                    throw new BaseException("目标状态为退款时，odrOrderRefund不能为空");
                }
                //校验odrOrderRefund类的属性
                checkOrderRefund(odrOrderRefund);
                //写入订单表
                odrOrder.setCaseReturnResult(odrOrderRefund.getCaseReturnResult());
                odrOrder.setCaseReturnStatus(odrOrderRefund.getCaseReturnStatus());
                try {
                    String masage = SMSSendCode.refund.getMasage();
                    SMSSend.sendSMS(odrOrder.getMobile(),
                            masage.replaceAll("xOrderId",request.getOrderId())
                                .replaceAll("xtime",DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"))
                                .replaceAll("xcode","退款"),
                            SMSSendCode.refund.getCode());
                } catch (Exception e) {
                    log.error("短信发送失败: ", e);
                }
            }

            OdrOrderFlowLog odrOrderFlowLog = new OdrOrderFlowLog();
            BeanUtils.copyProperties(request, odrOrderFlowLog);
            odrOrderFlowLog.setFlowTime(new Date());
            odrOrderFlowLogDao.insert(odrOrderFlowLog);
            //更新odr_order中订单状态为目标状态
            odrOrder.setOrderStatus(request.getTargetStatus());
            //odrOrder.setStatusUpdateTime(new SimpleDateFormat("yyyyMMddHHmmss").parse(request.getFlowTime()));
            odrOrder.setStatusUpdateTime(new Date());
            odrOrderDao.update(odrOrder);
        } catch (BaseException e) {
            throw new BaseException(e.getErrorMessage());
        } catch (Exception e) {
            log.error("订单状态流转失败: ", e);
            throw new BaseException("订单状态流转失败");
        }
    }

    private void checkOrderPay(OdrOrderPayReqVO odrOrderPayReqVO) {

        if (odrOrderPayReqVO.getPayNo() == null) {
            throw new BaseException("订单支付流水号不能为空");
        }
        if (ValidatorUtil.isEmpty(odrOrderPayReqVO.getOrderId())) {
            throw new BaseException("订单ID不能为空");
        }
        if (ValidatorUtil.isEmpty(odrOrderPayReqVO.getOrderPayType())) {
            throw new BaseException("订单支付方式不能为空");
        }
        if (odrOrderPayReqVO.getOrderCash() == null) {
            throw new BaseException("订单应付金额不能为空");
        }
        if (ValidatorUtil.isEmpty(odrOrderPayReqVO.getPayStatus())) {
            throw new BaseException("订单支付状态不能为空");
        }
        if (odrOrderPayReqVO.getPayTime() == null) {
            throw new BaseException("订单支付时间不能为空");
        }
    }

    private void checkOrderRefund(OdrOrderRefundReqVO odrOrderRefund) {

        if (ValidatorUtil.isEmpty(odrOrderRefund.getCaseReturnStatus())) {
            throw new BaseException("现金回退状态不能为空");
        }
        if (ValidatorUtil.isEmpty(odrOrderRefund.getCaseReturnResult())) {
            throw new BaseException("现金回退结果不能为空");
        }
    }

    public ResposeVO<OdrOrder> queryOdrOrderDetails(QueryOdrOrderDetailsReqVO queryOdrOrderDetailsReqVO) {
        try {
            ResposeVO<OdrOrder> resposeVO = new ResposeVO<>();
            OdrOrder odrOrder = odrOrderDao.selectByPrimaryKey(queryOdrOrderDetailsReqVO.getOrderId());
            OdrOrderPay odrOrderPay = odrOrderPayDao.selectByOrderId(queryOdrOrderDetailsReqVO.getOrderId());
            if (StrUtil.isBlankIfStr(odrOrder)) {
                resposeVO.setRespCode("9999");
                resposeVO.setRespDesc("订单不存在");
                return resposeVO;
            }
            odrOrder.setOdrOrderPay(odrOrderPay);
            resposeVO.setResult(odrOrder);
            return resposeVO;
        } catch (Exception e) {
            log.error("订单详细信息查询失败: ", e);
            throw new BaseException("订单详细信息查询查询失败");
        }
    }

    public ResposeListVO<OdrOrder> queryOdrOrderList(QueryOdrOrderReqVO queryOdrOrderReqVO) {
        try {
            //添加分页
            if (queryOdrOrderReqVO.getPage() != null && queryOdrOrderReqVO.getRows() != null) {
                PageHelper.startPage(queryOdrOrderReqVO.getPage(), queryOdrOrderReqVO.getRows());
            }
            if(StrUtil.isNotEmpty(queryOdrOrderReqVO.getStartTime())) {
                String startTime = queryOdrOrderReqVO.getStartTime();
                String s = DateUtil.format(DateUtil.parse(startTime + " 00:00:00", "yyyy-MM-dd HH:mm:ss"), "yyyyMMddHHmmss");
                String e = DateUtil.format(DateUtil.parse(startTime + " 23:59:59", "yyyy-MM-dd HH:mm:ss"), "yyyyMMddHHmmss");
                queryOdrOrderReqVO.setStartTime(s);
                queryOdrOrderReqVO.setEndTime(e);
            }
            List<OdrOrder> list = odrOrderDao.queryOdrOrderList(queryOdrOrderReqVO);
            ResposeListVO<OdrOrder> resposeVO = new ResposeListVO<>();
            PageInfo info = new PageInfo(list);
            resposeVO.setResult(info.getList());
            resposeVO.setTotalCount(info.getTotal());
            return resposeVO;
        } catch (Exception e) {
            log.error("订单列表查询失败: ", e);
            throw new BaseException("订单列表查询失败");
        }
    }


    public ResposeListVO<OdrOrderFlowLog> queryOdrOrderLog(String orderId, String userId, String userName,String preStatus, String targetStatus,
                                                           Integer pageNum, Integer pageSize) {
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<OdrOrder> list  = odrOrderFlowLogDao.selectList(orderId, preStatus, targetStatus);
            ResposeListVO<OdrOrderFlowLog> resposeVO = new ResposeListVO<>();
            PageInfo info = new PageInfo(list);
            resposeVO.setResult(info.getList());
            resposeVO.setTotalCount(info.getTotal());
            return resposeVO;
        } catch (Exception e) {
            log.error("订单操作日志查询失败: ", e);
            throw new BaseException("订单列表查询失败");
        }

    }


}